/// 白名单相关库
mod simple_list;
mod contract;
use ethereum_types::{H256, Address};
use common_types::{
    engines::machine::Call,
    ids::BlockId,
};
/// 引入white-user的spec格式
use ethjson::spec::WhiteUserSet as WhiteUserSetSpec;
use crate::simple_list::SimpleList;
use crate::contract::WhiteUserContract;
use engine::SystemCall;
use std::sync::Weak;
use client_traits::EngineClient;
/// 根据json文件来创建white-user-set格式
/// 包括三种格式来创建，列表格式，智能合约格式，列表+智能合约格式
/// 完成初始化操作
pub fn new_whiteuser_set_posdao(
    spec: WhiteUserSetSpec
) -> Box<dyn WhiteUserSet> {
    match spec {
        WhiteUserSetSpec::List(list) =>
            Box::new(SimpleList::new(list.into_iter().map(Into::into).collect())),
        WhiteUserSetSpec::Contract(address)=>{
            Box::new(WhiteUserContract::new(address.into()))
        },
        // WhiteUserSetSpec::Multi(multi) => {
        //
        // }
    }
}
/// 通过json来创建白名单列表
pub fn new_whiteuser_set(spec:WhiteUserSetSpec) -> Box<dyn WhiteUserSet> {
    new_whiteuser_set_posdao(spec)
}

/// 先只使用这两个方法,增加和删除以后再说
pub trait WhiteUserSet :Send + Sync + 'static{
    /// 包括几个方法，返回white-user列表，获得white-user数量，判断address是否是whie-user

    /// Checks if a given address is a whit-user,
    /// using underlying, default call mechanism.
    fn contains(&self, address: &Address) -> bool{
        let default = self.defalult_caller();
        self.contains_with_caller(address,&*default)
    }

    /// Returns the current number of white-user.
    fn count(&self) -> usize;

    fn contains_with_caller(&self,address:&Address,caller:&Call) -> bool;

    fn defalult_caller(&self) -> Box<Call>;

    // 添加新的接口
    fn register_client(&self, _client: Weak<dyn EngineClient>) {}

    // /// Checks if a given address is a white-user, with the given function
    // /// for executing synchronous calls to contracts.
    // fn contains_with_caller(&self, parent_block_hash: &H256, address: &Address, caller: &Call) -> bool;
    //
    //
    // /// Returns the current number of whit-users.
    // fn count_with_caller(&self, caller: &Call) -> usize;
    //
    // /// get the white-user-list
    // fn get_white_user_list(&self,caller:&Call) -> Vec<Addresss>;
}
